package lv.solcraft.replication.server.api;

import java.util.List;

import lv.solcraft.replication.server.bdb.Database;
import lv.solcraft.replication.server.bdb.TxTemplate;
import lv.solcraft.replication.server.boot.ServerConfig;
import lv.solcraft.replication.server.dao.OperDataAccess;
import lv.solcraft.replication.server.dao.OperSiteDataAccess;
import lv.solcraft.replication.server.model.OperSite;
import lv.solcraft.replication.server.model.OperState;

import org.apache.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.sleepycat.je.Transaction;

@Service
public class RetryAnalyser {

    private static final Logger logger = Logger.getLogger(RetryAnalyser.class);
    private static final int BATCH_SIZE = 1000;
    private Database database;
    private ServerConfig serverConfig;

    @Autowired
    public RetryAnalyser(Database database, ServerConfig serverConfig) {
        this.database = database;
        this.serverConfig = serverConfig;
    }

    public void execute() {
        for (Long site : serverConfig.getSitesList()) {
            executeForSite(site);
        }
    }

    private void executeForSite(final Long site) {
        final OperSiteDataAccess errorOpers = database.getOperSiteDataAccessFactory().getInstance(site, OperState.ERROR);
        logger.info("Starting retry analyser for site " + site);
        while (new TxTemplate<Boolean>(database, 10) {
            @Override
            protected Boolean executeInTx(Transaction tx) throws Exception {
                List<OperSite> operSites = errorOpers.findFirst(BATCH_SIZE);
                logger.debug("Found " + operSites.size() + " error opers");
                for (OperSite operSite : operSites) {
                    if (logger.isDebugEnabled())
                        logger.debug("Retrying oper site: " + operSite);
                    operSite.setState(OperState.NEW);
                    operSite.setMessage("RETRY: " + operSite.getMessage());
                    operSite.persist();
                }
                return !operSites.isEmpty();
            }
        }.execute()) {
        }
        logger.info("Finished retry analyser for site " + site);
    }
}
